/**
 * EduVerse Credentials - Polygon ID SDK初始化工具
 * 
 * 本模块提供了初始化Polygon ID JS SDK所需的工具函数。
 */

// 尝试加载真实的SDK模块
let polygonSDK;
try {
  polygonSDK = require('@0xpolygonid/js-sdk');
  console.log("成功加载@0xpolygonid/js-sdk");
} catch (error) {
  console.warn("无法加载@0xpolygonid/js-sdk，将使用模拟SDK:", error.message);
  polygonSDK = null;
}

const { ethers } = require('ethers');
const path = require('path');
const fs = require('fs');
const { 
  initMockSDK, 
  DidMethod, 
  Blockchain, 
  NetworkId,
  DataStorage,
  KeyStore,
  BjjProvider,
  CredentialStorage,
  IdentityStorage,
  InMemoryStateStorage,
  CredentialWallet = class {
    constructor(credentialStorage, identityStorage) {
      this.credentialStorage = credentialStorage;
      this.identityStorage = identityStorage;
    }
  },
  ProofService = class {
    constructor(identityStorage, credentialWallet, stateStorage, circuitsPath) {
      this.identityStorage = identityStorage;
      this.credentialWallet = credentialWallet;
      this.stateStorage = stateStorage;
      this.circuitsPath = circuitsPath;
    }
  }
} = require('./sdk-mock');

// 定义常量，确保sdk-init中也能访问
const DATA_STORAGE_PATH = process.env.DATA_STORAGE_PATH || '../data';
const CIRCUITS_PATH = process.env.CIRCUITS_PATH || '../circuits';

// 为了避免ReferenceError，确保在导入模拟SDK后再导出常量
console.log("从模拟SDK导入的常量:", {
  DidMethod,
  Blockchain,
  NetworkId
});

// 确认真实SDK导入的常量是否可用
if (polygonSDK && polygonSDK.DidMethod) {
  console.log("从真实SDK导入的常量可用");
}

/**
 * 初始化Polygon ID SDK
 * 
 * @param {Object} config 配置对象
 * @returns {Promise<Object>} 包含初始化的SDK组件
 */
async function initPolygonIdSDK(config = {}) {
  console.log("初始化Polygon ID SDK...");
  
  // 组件初始化超时设置（避免长时间阻塞）
  const INIT_TIMEOUT = 10000; // 10秒超时
  
  // 使用Promise.race实现超时功能
  return Promise.race([
    // 实际的SDK初始化过程
    (async () => {
      try {
        const dataStorage = new DataStorage(config.dataStoragePath || DATA_STORAGE_PATH);
        
        const circuitsPath = config.circuitsPath || CIRCUITS_PATH;
        console.log("Circuit Path:", circuitsPath);
        
        const keyStore = new KeyStore(dataStorage);
        const credentialStorage = new CredentialStorage(dataStorage);
        const identityStorage = new IdentityStorage(dataStorage);
        const privateKeyStorage = new BjjProvider(keyStore);
        const credentialWallet = new CredentialWallet(credentialStorage, identityStorage);
        
        // 配置以太坊状态存储
        const rpcUrl = config.rpcUrl || process.env.POLYGON_AMOY_RPC_URL;
        const stateContractAddress = config.stateContractAddress || process.env.STATE_CONTRACT_ADDRESS;
        
        const ethStateStorageConfig = {
          url: rpcUrl,
          defaultGasLimit: 600000,
          minGasPrice: "0",
          maxGasPrice: "100000000000",
          confirmationBlockCount: 5,
          confirmationTimeout: 600000,
          receiptTimeout: 600000,
          rpcResponseTimeout: 5000,
          waitReceiptCycleTime: 30000,
          waitBlockCycleTime: 3000
        };
        
        console.log("配置EthStateStorage:", ethStateStorageConfig);
        
        let stateStorage;
        try {
          // 检查是否提供了有效的RPC URL
          if (!rpcUrl || !rpcUrl.startsWith('http')) {
            throw new Error('无效的RPC URL');
          }
          
          console.warn("由于环境配置不完整，仅使用模拟SDK");
          throw new Error("强制使用模拟SDK");
          
          // 下面代码暂时不会执行，直到完成真实环境配置
          /*
          // 检查stateContract配置
          if (!stateContractAddress) {
            console.warn("未提供状态合约地址，尝试使用SDK默认地址");
            // 尝试获取适用于Amoy测试网的默认合约地址
            ethStateStorageConfig.contractAddress = '0x134B1BE34911E39A8397ec6289782989729807a4'; // Amoy测试网的示例地址
          }
          
          // 创建一个测试连接，确保RPC可以访问
          const testProvider = new ethers.JsonRpcProvider(rpcUrl);
          const networkInfo = await testProvider.getNetwork();
          console.log(`成功连接到网络: ${networkInfo.name}, 链ID: ${networkInfo.chainId}`);
          
          // 初始化状态存储
          stateStorage = new EthStateStorage(ethStateStorageConfig);
          */
        } catch (error) {
          console.warn("无法初始化EthStateStorage:", error.message);
          console.warn("使用模拟StateStorage代替");
          stateStorage = new InMemoryStateStorage();
        }
        
        // 加载Zero-Knowledge证明验证器
        const proofService = new ProofService(
          identityStorage,
          credentialWallet,
          stateStorage,
          circuitsPath
        );
          
        const identityWallet = {
          createIdentity: async (opts) => {
            return {
              did: {
                string: () => `did:${opts.method}:${opts.blockchain}:${opts.networkId}:${Date.now()}`
              },
              credential: { id: `auth-${Date.now()}` }
            };
          }
        };
        
        return {
          dataStorage,
          credentialWallet,
          identityWallet,
          proofService
        };
      } catch (error) {
        console.error("SDK初始化失败:", error);
        throw error;
      }
    })(),
    
    // 超时处理
    new Promise((_, reject) => 
      setTimeout(() => reject(new Error(`SDK初始化超时(${INIT_TIMEOUT}ms)`)), INIT_TIMEOUT)
    )
  ]);
}

module.exports = {
  initPolygonIdSDK,
  // 导出模拟SDK的常量，确保在任何情况下都有可用的常量
  DidMethod,
  Blockchain,
  NetworkId
}; 